package cn.mw.cmdb.virtualization.strategy.handler;

import cn.mw.cmdb.entity.InstanceInfo;
import cn.mw.cmdb.entity.ModelInfo;
import cn.mw.cmdb.param.BatchAddAndUpdInstanceParam;
import cn.mw.cmdb.param.InstanceIdsParam;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.service.ServiceAction;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.CustomModelServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.virtualization.constant.MwVirtualizationConstant;
import cn.mw.cmdb.virtualization.dto.VirtualizationStorageDto;
import cn.mw.cmdb.virtualization.param.VirtualizationParam;
import cn.mw.microMonitorCommon.entity.cmdb.DataSourceInstanceVo;
import cn.mw.microMonitorCommon.entity.common.MwSyncEngineDto;
import cn.mw.microMonitorCommon.enums.SyncEngineTypeEnum;
import cn.mw.microMonitorCommon.enums.UnicloudTypeEnum;
import cn.mw.microMonitorCommon.enums.VcenterTypeEnum;
import cn.mw.microMonitorCommon.util.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author gengjb
 * @description 同步引擎数据处理
 * @date 2024/6/24 10:41
 */
@Slf4j
public abstract class SyncEngineDataHandler {

    private final String MW_INSTANCENAME = "mw_instanceName";

    public abstract SyncEngineTypeEnum handlerType();

    /**
     * 获取虚拟化同步存储信息
     */
    public abstract List<VirtualizationStorageDto> getVirtualizationSyncStorageInfo(VirtualizationParam param, MwSyncEngineDto engineDto);


    public abstract void syncVirtualizationData(MwSyncEngineDto engineDto,VirtualizationParam param);

    /**
     * 处理同步数据
     * @param instanceVos
     */
    public void handlerInstanceData(List<DataSourceInstanceVo> instanceVos,String engineId,VirtualizationParam param) throws Exception {
        log.info("SyncEngineDataHandler{} handlerInstanceData() instanceVos::"+instanceVos);
        //获取dataID
        List<String> dataIds = new ArrayList<>();
        Map<String,DataSourceInstanceVo> instanceVoMap = new HashMap<>();
        for (DataSourceInstanceVo instanceVo : instanceVos) {
            Map<String, Object> instanceParams = instanceVo.getInstanceParams();
            if(instanceParams == null || !instanceParams.containsKey(MwVirtualizationConstant.ID)){continue;}
            dataIds.add(instanceParams.get(MwVirtualizationConstant.ID).toString());
            instanceVoMap.put(instanceParams.get(MwVirtualizationConstant.ID).toString(),instanceVo);
        }
        log.info("SyncEngineDataHandler{} handlerInstanceData() dataIds::"+dataIds);
        //根据数据ID查询数据
        InstanceSearchParam instanceSearchParam = new InstanceSearchParam();
        Map<String,Object> maps = new HashMap<>();
        maps.put(MwVirtualizationConstant.ENGINE_ID,engineId);
        instanceSearchParam.setData(maps);
        CmdbServiceManage cmdbServiceManage = SpringUtils.getBean(CmdbServiceManage.class);
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        List<InstanceInfo> instanceInfos = instanceService.doSelectList(instanceSearchParam);
        List<Map> insertDatas = new ArrayList<>();
        List<InstanceInfo> updateDatas = new ArrayList<>();
        List<String> deleteIds = new ArrayList<>();
        List<String> oldDataIds = new ArrayList<>();
        for (InstanceInfo instanceInfo : instanceInfos) {
            Map<String, Object> infoData = instanceInfo.getData();
            if(infoData == null || !infoData.containsKey(MwVirtualizationConstant.ID)){continue;}
            String dataId = infoData.get(MwVirtualizationConstant.ID).toString();
            oldDataIds.add(dataId);
            if(dataIds.contains(dataId)){
                DataSourceInstanceVo instanceVo = instanceVoMap.get(dataId);
                instanceInfo.setInBandIp(instanceVo.getHostIp());
                updateDatas.add(instanceInfo);
            }
            if(!dataIds.contains(dataId)){
                deleteIds.add(instanceInfo.getId());
            }
        }
        //获取新增的数据
        for (DataSourceInstanceVo instanceVo : instanceVos) {
            Map<String, Object> instanceParams = instanceVo.getInstanceParams();
            if(instanceParams == null || !instanceParams.containsKey(MwVirtualizationConstant.ID)){continue;}
            String dataId = instanceParams.get(MwVirtualizationConstant.ID).toString();
            String vmType = instanceParams.get(MwVirtualizationConstant.VM_TYPE).toString();
            if(!oldDataIds.contains(dataId)){
                instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getUsers),param.getUsers());
                instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getOrgIds),param.getOrgIds());
                instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getOrgs),param.getOrgs());
                instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getGroups),param.getGroups());
                VcenterTypeEnum vcenterTypeEnum = VcenterTypeEnum.getVcenterTypeEnum(vmType);
                if(vcenterTypeEnum != null){
                    instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getGroupId),vcenterTypeEnum.getGroupId());
                    instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getModelId),vcenterTypeEnum.getModelId());
                    insertDatas.add(instanceParams);
                    continue;
                }
                UnicloudTypeEnum unicloudTypeEnum = UnicloudTypeEnum.getUnicloudTypeEnumByType(vmType);
                if(unicloudTypeEnum != null){
                    instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getGroupId),unicloudTypeEnum.getGroupId());
                    instanceParams.put(CMDBTool.getFieldName(InstanceInfo::getModelId),unicloudTypeEnum.getModelId());
                }
                insertDatas.add(instanceParams);
            }
        }
        log.info("SyncEngineDataHandler{} handlerInstanceData() insertDatas::"+insertDatas);
        if(CollectionUtils.isNotEmpty(insertDatas)){
            BatchAddAndUpdInstanceParam batchAddAndUpdInstanceParam = new BatchAddAndUpdInstanceParam();
            batchAddAndUpdInstanceParam.setParams(insertDatas);
            cmdbServiceManage.service(batchAddAndUpdInstanceParam, ServiceAction.batchAdd);
        }
        log.info("SyncEngineDataHandler{} handlerInstanceData() updateDatas::"+updateDatas);
        if(CollectionUtils.isNotEmpty(updateDatas)){
            instanceService.doBatchUpdateMulti(updateDatas);
        }
        log.info("SyncEngineDataHandler{} handlerInstanceData() deleteIds::"+deleteIds);
        if(CollectionUtils.isNotEmpty(deleteIds)){
            InstanceIdsParam instanceIdsParam = new InstanceIdsParam();
            instanceIdsParam.setIds(deleteIds);
            instanceService.doBatchRemove(param);
        }
    }
}
